//package com.ruoyi.common.elasticsearch.configure;
//
//import co.elastic.clients.json.jackson.JacksonJsonpMapper;
//import co.elastic.clients.transport.rest_client.RestClientTransport;
//import org.apache.http.HttpHost;
//import org.apache.http.HttpResponse;
//import org.apache.http.nio.protocol.HttpAsyncResponseConsumer;
//import org.elasticsearch.client.HttpAsyncResponseConsumerFactory;
//import org.elasticsearch.client.RequestOptions;
//import org.elasticsearch.client.RestClient;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.boot.autoconfigure.AutoConfigureBefore;
//import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//
///**
// * Elasticsearch 客户端配置类
// *
// * @author samula
// */
//@Configuration
//@AutoConfigureBefore(ElasticsearchRestClientAutoConfiguration.class)
//public class ElasticSearchConfig {
//
//    @Value("${elasticsearch.host:127.0.0.1}")
//    private String elasticsearchHost;
//
//    @Value("${elasticsearch.port:9200}")
//    private int elasticsearchPort;
//
//    @Value("${elasticsearch.scheme:http}")
//    private String elasticsearchScheme;
//
//    @Value("${elasticsearch.token:}")
//    private static String elasticsearchToken;
//
//    @Value("${elasticsearch.token:}")
//    public void setElasticsearchToken(String token) {
//        ElasticSearchConfig.elasticsearchToken = token;
//    }
//
//    // 定义公共请求选项（带认证和合理资源配置）
//    // 定义公共请求选项（带认证和合理资源配置）
//    private static final RequestOptions COMMON_OPTIONS;
//    static {
//        RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();
//        // 添加认证头
//        if (elasticsearchToken != null && !elasticsearchToken.isEmpty()) {
//            builder.addHeader("Authorization", "Bearer " + elasticsearchToken);
//        }
//        // 设置合理的响应缓冲区大小（10MB）
//        builder.setHttpAsyncResponseConsumerFactory(
//                new HttpAsyncResponseConsumerFactory(
//                        new HttpAsyncResponseConsumerFactory.HeapBufferedResponseConsumerFactory(10 * 1024 * 1024)
//                )
//        );
//        COMMON_OPTIONS = builder.build();
//    }
////    private static final RequestOptions COMMON_OPTIONS;
////    static {
////        RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();
////        builder.addHeader("Authorization","Bearer" + TOKEN);
////        builder.setHttpAsyncResponseConsumerFactory(
////                new HttpAsyncResponseConsumerFactory(
////                        new HttpAsyncResponseConsumerFactory.HeapBufferedResponseConsumerFactory(30*1024*1024*1024)
////                );
////                COMMON_OPTIONS = builder.build();
////        );
////
////    }
//    /**
//     * 创建低级别的 RestClient
//     * (必须配置 destroyMethod = "close" 以确保资源正确释放)
//     */
//    @Bean(destroyMethod = "close")
//    public RestClient restClient() {
//        // 使用从配置文件注入的变量
//        return RestClient.builder(
//                new HttpHost(elasticsearchHost, elasticsearchPort, elasticsearchScheme)
//        ).build();
//    }
//
//    /**
//     * 创建 Transport 对象
//     * (不需要 destroyMethod)
//     */
//    @Bean
//    public RestClientTransport transport(RestClient restClient) {
//        return new RestClientTransport(
//                restClient, new JacksonJsonpMapper()
//        );
//    }
//
//    /**
//     * 创建高级别的 ElasticsearchClient
//     * (不需要 destroyMethod)
//     */
//    @Bean
//    public co.elastic.clients.elasticsearch.ElasticsearchClient elasticsearchClient(RestClientTransport transport) {
//        return new co.elastic.clients.elasticsearch.ElasticsearchClient(transport);
//    }
//}


package com.ruoyi.common.elasticsearch.configure;

import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import org.apache.http.HttpHost;
import org.apache.http.impl.nio.reactor.IOReactorConfig;
import org.elasticsearch.client.HttpAsyncResponseConsumerFactory;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Elasticsearch 客户端配置类（带认证和合理资源配置）
 *
 * @author samula
 */
@Configuration
@AutoConfigureBefore(ElasticsearchRestClientAutoConfiguration.class)
public class ElasticSearchConfig {

    @Value("${elasticsearch.host:127.0.0.1}")
    private String elasticsearchHost;

    @Value("${elasticsearch.port:9200}")
    private int elasticsearchPort;

    @Value("${elasticsearch.scheme:http}")
    private String elasticsearchScheme;

    // 静态字段存储认证令牌
    private static String elasticsearchToken;

    // 通过setter方法注入值（Spring会自动调用）
    @Value("${elasticsearch.token:}")
    public void setElasticsearchToken(String token) {
        ElasticSearchConfig.elasticsearchToken = token;
    }

    // 定义公共请求选项（带认证和合理资源配置）
    private static final RequestOptions COMMON_OPTIONS;
    static {
        RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();
        // 添加认证头
        if (elasticsearchToken != null && !elasticsearchToken.isEmpty()) {
            builder.addHeader("Authorization", "Bearer " + elasticsearchToken);
        }
        // 设置合理的响应缓冲区大小（10MB）
        // 正确用法：直接使用具体实现类 HeapBufferedResponseConsumerFactory
        builder.setHttpAsyncResponseConsumerFactory(
                new HttpAsyncResponseConsumerFactory.HeapBufferedResponseConsumerFactory(10 * 1024 * 1024)
        );
        COMMON_OPTIONS = builder.build();
    }

    /**
     * 创建低级别的 RestClient
     */
    @Bean(destroyMethod = "close")
    public RestClient restClient() {
//        return RestClient.builder(
//                new HttpHost(elasticsearchHost, elasticsearchPort, elasticsearchScheme)
//        ).build();
        return RestClient.builder(
                        new HttpHost(elasticsearchHost, elasticsearchPort, elasticsearchScheme)
                )
                .setRequestConfigCallback(requestConfigBuilder ->
                        requestConfigBuilder
                                .setConnectTimeout(5000)     // 连接超时 5秒
                                .setSocketTimeout(30000)    // 套接字超时 30秒
                                .setConnectionRequestTimeout(5000) // 连接请求超时 1秒
                )
                .setHttpClientConfigCallback(httpClientBuilder -> {
                    // 配置连接池参数（使用 org.apache.hc.core5.http.config.IOReactorConfig）
                    httpClientBuilder.setDefaultIOReactorConfig(
                            IOReactorConfig.custom()
                                    .setIoThreadCount(Runtime.getRuntime().availableProcessors() * 2)
                                    .build()
                    );
                    return httpClientBuilder;
                })
                .build();
    }

    /**
     * 创建 Transport 对象
     */
    @Bean
    public RestClientTransport transport(RestClient restClient) {
        return new RestClientTransport(
                restClient, new JacksonJsonpMapper()
        );
    }

    /**
     * 创建高级别的 ElasticsearchClient
     */
    @Bean
    public co.elastic.clients.elasticsearch.ElasticsearchClient elasticsearchClient(RestClientTransport transport) {
        return new co.elastic.clients.elasticsearch.ElasticsearchClient(transport);
    }

    /**
     * 暴露公共请求选项，供业务代码使用
     */
    @Bean
    public RequestOptions commonRequestOptions() {
        return COMMON_OPTIONS;
    }
}